package com.eurasia.assignment.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eurasia.assignment.controller.dto.ProjectSearchRequest;
import com.eurasia.assignment.domain.Project;
import com.eurasia.assignment.infrastructure.entity.ProjectEntity;
import com.eurasia.assignment.infrastructure.repository.ProjectRepository;

@Service
public class ProjectService {
    private final ProjectRepository projectRepository;
    private final FileService fileService;

    @Autowired
    public ProjectService(ProjectRepository projectRepository, FileService fileService) {
        this.projectRepository = projectRepository;
        this.fileService = fileService;
    }

    @Transactional
    public Project createProject(Project project) {
        ProjectEntity entity = ProjectEntity.fromDomain(project);
        ProjectEntity savedEntity = projectRepository.save(entity);
        return savedEntity.toDomain();
    }

    public Project getProjectById(Long id) {
        return projectRepository.findById(id)
            .map(ProjectEntity::toDomain)
            .orElseThrow(() -> new RuntimeException("Project not found with id: " + id));
    }

    public List<Project> getAllProjects() {
        return projectRepository.findAll().stream()
            .map(ProjectEntity::toDomain)
            .collect(Collectors.toList());
    }

    @Transactional
    public Project updateProject(Long id, Project projectDetails) {
        ProjectEntity existingEntity = projectRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Project not found with id: " + id));
        
        // Update fields
        existingEntity.setName(projectDetails.getName());
        existingEntity.setCourse(projectDetails.getCourse());
        existingEntity.setType(projectDetails.getType());
        existingEntity.setFinishTime(projectDetails.getFinishTime());
        existingEntity.setStatus(projectDetails.getStatus());
        existingEntity.setScore(projectDetails.getScore());
        existingEntity.setPoints(projectDetails.getPoints());
        
        ProjectEntity updatedEntity = projectRepository.save(existingEntity);
        return updatedEntity.toDomain();
    }

    @Transactional
    public void deleteProject(Long id) {
        if (!projectRepository.existsById(id)) {
            throw new RuntimeException("Project not found with id: " + id);
        }
        projectRepository.deleteById(id);
    }

    public List<Project> searchProjects(ProjectSearchRequest searchRequest) {
        return projectRepository.findAll().stream()
            .map(ProjectEntity::toDomain)
            .filter(project -> matchesSearchCriteria(project, searchRequest))
            .collect(Collectors.toList());
    }
    
    public Page<Project> searchProjectsWithPagination(ProjectSearchRequest searchRequest, int page, int size) {
        // 获取所有匹配的项目
        List<Project> filteredProjects = projectRepository.findAll().stream()
                .map(ProjectEntity::toDomain)
                .filter(project -> matchesSearchCriteria(project, searchRequest))
                .collect(Collectors.toList());
        
        // 手动分页
        Pageable pageable = PageRequest.of(page, size);
        int start = (int) pageable.getOffset();
        int end = Math.min((start + pageable.getPageSize()), filteredProjects.size());
        
        // 考虑边界情况
        if (start > filteredProjects.size()) {
            return new PageImpl<>(List.of(), pageable, filteredProjects.size());
        }
        
        List<Project> pageContent = filteredProjects.subList(start, end);
        
        // 创建分页结果
        return new PageImpl<>(pageContent, pageable, filteredProjects.size());
    }

    private boolean matchesSearchCriteria(Project project, ProjectSearchRequest searchRequest) {
        if (searchRequest.getName() != null && !searchRequest.getName().isEmpty()) {
            if (!project.getName().toLowerCase().contains(searchRequest.getName().toLowerCase())) {
                return false;
            }
        }
        
        if (searchRequest.getCourse() != null && !searchRequest.getCourse().isEmpty()) {
            if (!project.getCourse().toLowerCase().contains(searchRequest.getCourse().toLowerCase())) {
                return false;
            }
        }
        
        if (searchRequest.getType() != null && !searchRequest.getType().isEmpty()) {
            if (!project.getType().equals(searchRequest.getType())) {
                return false;
            }
        }
        
        if (searchRequest.getStatus() != null && !searchRequest.getStatus().isEmpty()) {
            if (!project.getStatus().equals(searchRequest.getStatus())) {
                return false;
            }
        }
        
        return true;
    }
} 